
__author__ = 'DSperansky'

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import NoAlertPresentException
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import random

import unittest

list_movies = [['My movie ' + str(random.choice(range(1,100))), '2012', 'This movie will be created']
                ,['', '2012', 'This movie will not be created']]

class TestCreateDelete(unittest.TestCase):

    driver = None

    @staticmethod
    def setUpClass():
        TestCreateDelete.driver = webdriver.Chrome()
        #TestCreateDelete.driver.maximize_window()

    def setUp(self):
        self.wait = WebDriverWait(TestCreateDelete.driver, 15)
        #self.driver.implicitly_wait(30)
        self.base_url = "http://localhost/"
        self.verificationErrors = []
        self.accept_next_alert = True
        #self.movie_ids = list()
        self.do_login()

    def test_1_create_movie_positive(self):
        """ Test of adding movie with all required parameters provided - movie should be successfully added
        and movie info page should be displayed """
        wait = self.wait
        #On main page
        #add_movie_xpath_locator = "//nav//li[1]/div[@class='button']"
        add_movie_css_locator = "nav li:first-of-type>div.button img"
        wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, add_movie_css_locator))).click()
        #On edit movie page
        self.fill_movie_form(list_movies[0])
        self.assertTrue(self.is_movie_info_page())

    def test_2_create_movie_negative(self):
        """ Test of adding movie with one of required parameters missing- movie should not be added
        and browser should remain on edit movie page """
        #On main page
        add_movie_css_locator = "nav li:first-of-type>div.button img"
        self.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, add_movie_css_locator))).click()
        #On edit movie page
        self.fill_movie_form(list_movies[1])
        self.assertFalse(self.is_movie_info_page())

    def test_3_delete_movie(self):
        initial_movie_ids =  self.get_movie_ids()
        if len(initial_movie_ids) > 0:
            id = random.choice(initial_movie_ids)
            movie_with_id_css_locator = "div#results>a>div[id='movie_" + str(id) +"']"
            self.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, movie_with_id_css_locator))).click()
            delete_button_css_locator = "nav li:last-of-type>div.button img"
            self.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, delete_button_css_locator))).click()
            self.wait.until(EC.alert_is_present()).accept()
            remaining_movie_ids = self.get_movie_ids()
            self.assertTrue(id not in remaining_movie_ids)
        else:
            print 'No movies found - nothing to delete!'

    def get_movie_ids(self):
        all_movies_css_locator = "div#results>a>div"
        wait = WebDriverWait(TestCreateDelete.driver, 5)
        try:
            lst_movies = wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, all_movies_css_locator)))
            lst_ids = [str(movie.get_attribute("id")).split('_')[1] for movie in lst_movies]
        except TimeoutException, e:
            lst_ids = []
        return lst_ids

    def is_movie_info_page(self):
        """ Method verifies that Movie info page is displayed """
        current_url = str(self.driver.current_url)
        if current_url.count('=') == 2:
            url_split = current_url.split('=')
            if url_split[2].isdigit():
                return True
            return False
        return False

    def fill_movie_form(self, movie):
        """ Method fills movie information on edit movie page """
        #On edit movie page
        title_input_css_locator = "input[name='name']"
        year_input_css_locator = "input[name='year']"
        notes_tarea_css_locator = "textarea[name='notes']"
        save_button_css_locator = "input#submit"
        self.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR,  title_input_css_locator))).send_keys(movie[0])
        self.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR,  year_input_css_locator))).send_keys(movie[1])
        self.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR,  notes_tarea_css_locator))).send_keys(movie[2])
        self.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR,  save_button_css_locator))).click()

    def do_login(self):
        """ Method loads initial page and performs login """
        #driver = self.driver
        self.driver.get(self.base_url + "/php4dvd/")
        self.wait.until(EC.visibility_of_element_located((By.ID,"username"))).clear()
        self.wait.until(EC.visibility_of_element_located((By.ID,"username"))).send_keys("admin")
        self.wait.until(EC.visibility_of_element_located((By.NAME,"password"))).clear()
        self.wait.until(EC.visibility_of_element_located((By.NAME,"password"))).send_keys("admin")
        self.wait.until(EC.visibility_of_element_located((By.NAME,"submit"))).click()

    def do_logout(self):
        """ Method performs logout procedure """
        logout_link_css_locator = "header nav li:last-of-type>a"
        self.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR,  logout_link_css_locator))).click()
        self.wait.until(EC.alert_is_present()).accept()

    """

    def is_element_present(self, how, what):
        try: self.driver.find_element(by=how, value=what)
        except NoSuchElementException, e: return False
        return True

    def is_alert_present(self):
        try: self.driver.switch_to_alert()
        except NoAlertPresentException, e: return False
        return True

    def close_alert_and_get_its_text(self):
        try:
            alert = self.driver.switch_to_alert()
            alert_text = alert.text
            if self.accept_next_alert:
                alert.accept()
            else:
                alert.dismiss()
            return alert_text
        finally: self.accept_next_alert = True

    """

    def tearDown(self):
        self.do_logout()
        self.assertEqual([], self.verificationErrors)

    @staticmethod
    def tearDownClass():
        TestCreateDelete.driver.quit()

if __name__ == "__main__":
    unittest.main()
